﻿using System;
using JSM.DataStore;
using Newtonsoft.Json;

namespace JSM
{
	/// <summary>
	/// HTML Helper for the javascript model.
	/// </summary>
	public static class JSMHtmlHelper
	{
		/// <summary>
		/// Gets the Init-Javascript which is responsible to fire the Init-event.
		/// </summary>
		/// <param name="javaScriptModelAware">
		/// The object which is aware of the javascript model. Provide this object if you want to use the default data store provider.
		/// </param>
		/// <param name="dataStoreProvider">
		/// The data store provider. Provide this object if you want to use it as data store provider.
		/// </param>
		/// <returns>
		/// A string containing javascript.
		/// </returns>
		public static string GetInitJavaScript(IJavaScriptModelAware javaScriptModelAware, IDataStoreProvider dataStoreProvider)
		{
			JavaScriptModel javaScriptModel = GetJavaScriptModel(javaScriptModelAware, dataStoreProvider);

			return string.Format("JSMController.Init({0}, {1});",
				JsonConvert.SerializeObject(javaScriptModel.GetVariables(PageLoadEvent.Init)),
				JsonConvert.SerializeObject(javaScriptModel.GetFunctions(PageLoadEvent.Init)));
		}

		/// <summary>
		/// Gets the InitReady-Javascript which is responsible to fire the InitReady-event.
		/// </summary>
		/// <returns>
		/// A string containing javascript.
		/// </returns>
		public static string GetInitReadyJavaScript()
		{
			return "JSMController.InitReady();";
		}

		/// <summary>
		/// Gets the html-container for the variables and functions.
		/// </summary>
		/// <param name="javaScriptModelAware">
		/// The object which is aware of the javascript model. Provide this object if you want to use the default data store provider.
		/// </param>
		/// <param name="dataStoreProvider">
		/// The data store provider. Provide this object if you want to use it as data store provider.
		/// </param>
		/// <returns>
		/// A string containing html and the embedded variables/functions.
		/// </returns>
		public static string GetJavaScriptModelContainer(IJavaScriptModelAware javaScriptModelAware, IDataStoreProvider dataStoreProvider)
		{
			JavaScriptModel javaScriptModel = GetJavaScriptModel(javaScriptModelAware, dataStoreProvider);

			return string.Format("<div id=\"JSMVariables\" style=\"display: none;\"><!--[if true]>{0}<![endif]--></div><div id=\"JSMFunctions\" style=\"display: none;\"><!--[if true]>{1}<![endif]--></div>",
				JsonConvert.SerializeObject(javaScriptModel.GetVariables()).Replace("<", "\\u003c").Replace(">", "\\u003e"),
				JsonConvert.SerializeObject(javaScriptModel.GetFunctions()).Replace("<", "\\u003c").Replace(">", "\\u003e"));
		}

		/// <summary>
		/// Gets the <see cref="JavaScriptModel"/> either from the provided data store provider or from the default data store provider. 
		/// </summary>
		/// <param name="javaScriptModelAware">
		/// The object which is aware of the javascript model. Provide this object if you want to use the default data store provider.
		/// </param>
		/// <param name="dataStoreProvider">
		/// The data store provider. Provide this object if you want to use it as data store provider.
		/// </param>
		/// <returns>
		/// The <see cref="JavaScriptModel"/> from the provided data store provider.
		/// </returns>
		private static JavaScriptModel GetJavaScriptModel(IJavaScriptModelAware javaScriptModelAware, IDataStoreProvider dataStoreProvider)
		{
			JavaScriptModel javaScriptModel = JavaScriptModel.GetJavaScriptModel(javaScriptModelAware, dataStoreProvider);
			if (javaScriptModel == null)
				throw new Exception("No JavaScriptModel found. Please check your data store provider.");
			return javaScriptModel;
		}
	}
}
